package com.zjj.edu.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.zjj.edu.common.annotation.DataScope;
import com.zjj.edu.common.constant.UserConstants;
import com.zjj.edu.common.core.text.Convert;
import com.zjj.edu.common.exception.BusinessException;
import com.zjj.edu.common.utils.StringUtils;
import com.zjj.edu.system.domain.*;
import com.zjj.edu.system.mapper.*;
import com.zjj.edu.system.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 租户 业务层处理
 * 
 * @author zjj
 */
@Service
public class SysTenantServiceImpl implements ISysTenantService {

	@Autowired
	private SysTenantMapper tenantMapper;

	@Autowired
	private SysTenantApplicationMapper tenantApplicationMapper;

	@Autowired
	private SysRoleMapper roleMapper;

	@Autowired
	private SysUserRoleMapper userRoleMapper;

	@Autowired
	private SysMenuMapper menuMapper;

	@Autowired
	private SysRoleMenuMapper roleMenuMapper;

	@Autowired
	private SysRoleDeptMapper roleDeptMapper;

	@Autowired
	private ISysDeptService deptService;

	@Autowired
	private ISysRoleService roleService;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ISysDictDataService dictDataService;

	@Autowired
	private ISysGradeService gradeService;

	@Autowired
	private ISysSubjectService subjectService;

	@Autowired
	private ISysClassTypeService classTypeService;

	@Autowired
	private ISysPostService postService;

	@Autowired
	private ISysSemesterService semesterService;

	/**
	 * 根据条件分页查询租户数据
	 * 
	 * @param tenant
	 *            租户信息
	 * @return 租户数据集合信息
	 */
	@Override
	@DataScope(deptAlias = "d")
	public List<SysTenant> selectTenantList(SysTenant tenant) {
		return tenantMapper.selectTenantList(tenant);
	}

	/**
	 * 查询所有租户
	 * 
	 * @return 租户列表
	 */
	@Override
	public List<SysTenant> selectTenantAll() {
		return tenantMapper.selectTenantAll();
	}

	/**
	 * 通过租户ID查询租户
	 * 
	 * @param tenantId
	 *            租户ID
	 * @return 租户对象信息
	 */
	@Override
	public SysTenant selectTenantById(Long tenantId) {
		return tenantMapper.selectTenantById(tenantId);
	}

	/**
	 * 通过租户ID删除租户
	 * 
	 * @param tenantId
	 *            租户ID
	 * @return 结果
	 */
	@Override
	public boolean deleteTenantById(Long tenantId) {
		return tenantMapper.deleteTenantById(tenantId) > 0 ? true : false;
	}

	/**
	 * 批量删除租户信息
	 * 
	 * @param ids
	 *            需要删除的数据ID
	 * @throws Exception
	 */
	@Override
	public int deleteTenantByIds(String ids) throws BusinessException {
		Long[] tenantIds = Convert.toLongArray(ids);
		return tenantMapper.deleteTenantByIds(tenantIds);
	}

	/**
	 * 新增保存租户信息
	 * 
	 * @param Tenant
	 *            租户信息
	 * @return 结果
	 */
	@Override
	public int insertTenant(SysTenant Tenant) {
		// 新增租户信息
		return tenantMapper.insertTenant(Tenant);
	}

	/**
	 * 修改保存租户信息
	 * 
	 * @param Tenant
	 *            租户信息
	 * @return 结果
	 */
	@Override
	@Transactional
	public int updateTenant(SysTenant Tenant) {
		// 修改租户信息
		tenantMapper.updateTenant(Tenant);
		return tenantMapper.updateTenant(Tenant);
	}

	@Override
	public int changeStatus(SysTenant tenant) {
		return 0;
	}

	/**
	 * 校验岗位名称是否唯一
	 * 
	 * @param tenant
	 *            租户信息
	 * @return 结果
	 */
	@Override
	public String checkTenantNameUnique(SysTenant tenant) {
		Long tenantId = StringUtils.isNull(tenant.getTenantId()) ? -1L : tenant.getTenantId();
		SysTenant info = tenantMapper.checkTenantNameUnique(tenant.getTenantName());
		if (StringUtils.isNotNull(info) && info.getTenantId().longValue() != tenantId.longValue()) {
			return UserConstants.TENANT_NAME_NOT_UNIQUE;
		}
		return UserConstants.TENANT_NAME_UNIQUE;
	}

	/**
	 * 校验租户编码是否唯一
	 *
	 * @param tenant
	 *            租户信息
	 * @return 结果
	 */
	public String checkTenantCodeUnique(SysTenant tenant) {
		Long tenantId = StringUtils.isNull(tenant.getTenantId()) ? -1L : tenant.getTenantId();
		SysTenant info = tenantMapper.checkTenantCodeUnique(tenant.getTenantCode());
		if (StringUtils.isNotNull(info) && info.getTenantId().longValue() != tenantId.longValue()) {
			return UserConstants.TENANT_NAME_NOT_UNIQUE;
		}
		return UserConstants.TENANT_NAME_UNIQUE;
	}

	@Override
	public List<SysTenantApplication> selectTenantApplicationByTenantId(Long tenantId) {
		return tenantApplicationMapper.getTenantApplicationByTenantId(tenantId);
	}

	@Override
	public int authApplication(SysTenantApplication tenantApplication, String loginName) {
		//查询该租户信息
		SysTenant tenant = tenantMapper.selectTenantById(tenantApplication.getTenantId());
		if (tenant == null) {
			return 0;
		}
		tenant.setUpdateBy(loginName);

		//先查询该租户是否分配了子系统
		List<SysTenantApplication> tenantAppList = tenantApplicationMapper.getTenantApplicationByTenantId(tenantApplication.getTenantId());

		//查询租户下的角色
		List<SysRole> sysRoles = roleMapper.getSysRoleByTenantId(tenantApplication.getTenantId());
		if (tenantAppList != null && tenantAppList.size() > 0) {
			//存废除的
			List<String> oldAppCodes = new ArrayList<String>();

			for (SysTenantApplication sysTenantApplication : tenantAppList) {
				String dbAppCode = sysTenantApplication.getAppCode();
				boolean flag = tenantApplication.getAppCodes().contains(dbAppCode);
				if (!flag) {
					oldAppCodes.add(sysTenantApplication.getAppCode());
				}
			}
			//存新增的
			List<String> newAppCodes = (List<String>) CollUtil.disjunction(tenantApplication.getAppCodes(), getAppCodes(tenantAppList));

			//清空旧的角色关联的菜单和关联租户
			if (oldAppCodes != null && oldAppCodes.size() > 0) {
				deleteOldRoleMensTenant(tenantApplication.getTenantId(), oldAppCodes, sysRoles);
			}
			//编辑时添加新的系统关联信息
			if (newAppCodes != null && newAppCodes.size() > 0) {
				//添加关联租户关联系统
				tenantApplicationMapper.batchTenantApplication(tenantApplication.getTenantId(), newAppCodes);
				//添加角色关联的菜单
				insertMenuRoles(newAppCodes, sysRoles);
			}
		} else {
			//只在第一次分配系统时创建
			//添加关联租户关联系统
			tenantApplicationMapper.batchTenantApplication(tenantApplication.getTenantId(), tenantApplication.getAppCodes());

			//创建部门
			SysDept dept = deptService.insertSysDeptDefault(tenant);
			// 初始化生成部门
			this.initDeptData(tenant, dept.getDeptId());

			//创建角色
			SysRole role = roleService.insertSysRoleDefault(tenant);

			//创建角色关联部门
			List<SysRoleDept> roleDeptList = getSysRoleDepts(dept, role);
			roleDeptMapper.batchRoleDept(roleDeptList);

			//添加角色关联菜单
			List<SysRole> roles = new ArrayList<>();
			roles.add(role);
			insertMenuRoles(tenantApplication.getAppCodes(), roles);

			//创建用户
			SysUser user = userService.insertUserDefault(tenant, dept);

			//添加用户归属角色
			List<SysUserRole> userRoles = getSysUserRoles(role, user);
			userRoleMapper.batchUserRole(userRoles);

			// 初始化生成年级
			this.initGradeData(tenant);

			// 初始化生成科目
			this.initSubjectData(tenant);

			// 初始化生成班级类型
			this.initClassTypeData(tenant);

			// 初始化生成岗位
			this.initPostData(tenant);

			// 初始化生成学期
			this.initSemesterData(tenant);
		}
		return 1;
	}

	/**
	 * 初始化生成班级类型
	 */
	private void initClassTypeData(SysTenant tenant) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_class_type");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysClassType classType = new SysClassType();
				classType.setTenantId(tenant.getTenantId());
				classType.setName(t.getDictValue());
				classType.setOrderNum(t.getDictSort());
				classType.setCreateBy(tenant.getUpdateBy());
				classTypeService.insertSysClassType(classType);
			}
		}
	}


	/**
	 * 初始化生成岗位
	 */
	private void initPostData(SysTenant tenant) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_post");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysPost post = new SysPost();
				post.setTenantId(tenant.getTenantId());
				post.setPostName(t.getDictValue());
				post.setPostCode("test");
				post.setStatus("0");
				post.setPostSort(t.getDictSort() + "");
				post.setCreateBy(tenant.getUpdateBy());
				postService.insertPost(post);
			}
		}
	}

	/**
	 * 初始化生成部门
	 */
	private void initDeptData(SysTenant tenant, long parentId) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_dept");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysDept dept = new SysDept();
				dept.setTenantId(tenant.getTenantId());
				dept.setDeptName(t.getDictValue());
				dept.setParentId(parentId);
				dept.setOrderNum(t.getDictSort() + "");
				dept.setCreateBy(tenant.getUpdateBy());
				deptService.insertDept(dept);
			}
		}
	}

	/**
	 * 初始化生成学期
	 */
	private void initSemesterData(SysTenant tenant) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_semester");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysSemester semester = new SysSemester();
				semester.setTenantId(tenant.getTenantId());
				semester.setName(t.getDictValue());
				semester.setOrderNum(t.getDictSort());
				semester.setCreateBy(tenant.getUpdateBy());
				semesterService.insertSysSemester(semester);
			}
		}
	}

	/**
	 * 初始化生成科目
	 */
	private void initSubjectData(SysTenant tenant) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_subject");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysSubject subject = new SysSubject();
				subject.setTenantId(tenant.getTenantId());
				subject.setName(t.getDictValue());
				subject.setOrderNum(t.getDictSort());
				subject.setCreateBy(tenant.getUpdateBy());
				subjectService.insertSysSubject(subject);
			}
		}
	}

	/**
	 * 初始化生成年级
	 */
	private void initGradeData(SysTenant tenant) {
		SysDictData dictData = new SysDictData();
		dictData.setDictType("tenant_grade");
		List<SysDictData> list = dictDataService.selectInitDictDataList(dictData);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SysDictData t:list) {
				SysGrade grade = new SysGrade();
				grade.setTenantId(tenant.getTenantId());
				grade.setName(t.getDictValue());
				grade.setOrderNum(t.getDictSort());
				grade.setCreateBy(tenant.getUpdateBy());
				gradeService.insertSysGrade(grade);
			}
		}
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	private List<String> getAppCodes(List<SysTenantApplication> list) {
		List<String> aList = new ArrayList<>();
		for (SysTenantApplication vo: list) {
			aList.add(vo.getAppCode());
		}
		return aList;
	}

	/**
	 * 删除角色跟菜单的关联
	 *
	 * @param tenantId
	 * @param appCodes
	 * @param sysRoles
	 */
	private void deleteOldRoleMensTenant(long tenantId, List<String> appCodes, List<SysRole> sysRoles) {
		for (String appCode : appCodes) {
			tenantApplicationMapper.deleteTenantApplicationByTenantId(tenantId, appCode);
			List<SysMenu> sysMenus = menuMapper.selectMenuByAppCode(appCode);
			if (sysMenus != null && sysMenus.size() > 0 && sysRoles != null && sysRoles.size() > 0) {
				for (SysRole role : sysRoles) {
					roleMenuMapper.deleteRoleMenusAndRoleId(sysMenus, role.getRoleId());
				}
			}
		}
	}

	/**
	 * 根据系统添加角色与菜单的关联
	 *
	 * @param appCodes
	 * @param roles
	 */
	private void insertMenuRoles(List<String> appCodes, List<SysRole> roles) {
		for (String appCode : appCodes) {
			List<SysMenu> sysMenus = menuMapper.selectMenuByAppCode(appCode);
			if (sysMenus != null && sysMenus.size() > 0 && roles != null && roles.size() > 0) {
				batchInsertRolesMenus(roles, sysMenus);
			}
		}
	}

	/**
	 *
	 * @param roles
	 * @param sysMenus
	 */
	private void batchInsertRolesMenus(List<SysRole> roles, List<SysMenu> sysMenus) {
		List<SysRoleMenu> sysRoleMenus = new ArrayList();
		for (SysRole role : roles) {
			for (SysMenu menu : sysMenus) {
				SysRoleMenu sysRoleMenu = new SysRoleMenu();
				sysRoleMenu.setMenuId(menu.getMenuId());
				sysRoleMenu.setRoleId(role.getRoleId());
				sysRoleMenus.add(sysRoleMenu);
			}
		}
		roleMenuMapper.batchRoleMenu(sysRoleMenus);
	}

	/**
	 * 封装角色关联部门
	 * @param dept
	 * @param role
	 * @return
	 */
	private List<SysRoleDept> getSysRoleDepts(SysDept dept, SysRole role) {
		List<SysRoleDept> roleDeptList = new ArrayList<>();
		SysRoleDept roleDept = new SysRoleDept();
		roleDept.setDeptId(dept.getDeptId());
		roleDept.setRoleId(role.getRoleId());
		roleDeptList.add(roleDept);
		return roleDeptList;
	}

	/**
	 * 封装用户、角色数据
	 * @param role
	 * @param user
	 * @return
	 */
	private List<SysUserRole> getSysUserRoles(SysRole role, SysUser user) {
		List<SysUserRole> userRoles = new ArrayList<>();
		SysUserRole userRole = new SysUserRole();
		userRole.setRoleId(role.getRoleId());
		userRole.setUserId(user.getUserId());
		userRoles.add(userRole);
		return userRoles;
	}

}
